/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.letmeshare.stockkeeper.purchase.service;

import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import org.letmeshare.stockkeeper.PersistenceManager;
import org.letmeshare.stockkeeper.common.Status;
import org.letmeshare.stockkeeper.common.exception.InvalidActionException;
import org.letmeshare.stockkeeper.purchase.entities.Purchase;
import org.letmeshare.stockkeeper.purchase.entities.PurchaseEntry;
import org.letmeshare.stockkeeper.purchase.module.PurchaseModule;
import org.letmeshare.stockkeeper.stock.entities.Item;
import org.letmeshare.stockkeeper.stock.entities.Stock;
import org.letmeshare.stockkeeper.stock.module.StockModule;

/**
 *
 * @author gAmE wOrLd
 */
public class PurchaseService {

    private EntityManager em;
    private PurchaseModule purchaseModule;
    private StockModule stockModule;
    private EntityTransaction txn;
    private Purchase currentPurchase;

    public static PurchaseService getInstance() {
        return new PurchaseService();
    }

    private PurchaseService() {
        em = PersistenceManager.getEntityManager();
        purchaseModule = PurchaseModule.getInstance(em);
        stockModule = StockModule.getInstance(em);
    }

    public Purchase newPurchase() {
        if (txn != null) {
            txn.rollback();
        }
        txn = em.getTransaction();
        txn.begin();
        currentPurchase = new Purchase();
        currentPurchase.setBilledOn(new Date());
        currentPurchase.setStatus(Status.CREATED);
        return currentPurchase;
    }

    public void commitPurchase() {
        if (txn == null || !txn.isActive()) {
            throw new InvalidActionException("No active purchase");
        }
        currentPurchase.setStatus(Status.COMMITTED);
        currentPurchase.validate();
        purchaseModule.commitPurchase(currentPurchase);
        txn.commit();
        txn = null;
    }
    
    public List<Stock> getAllStocks(){
        return stockModule.getAllStocks();
    }
    
    public Stock getStockById(String id){
        return stockModule.getStock(id);
    }
    
    public void addStock(Stock stock, double qty) {
        if (txn == null || !txn.isActive() || currentPurchase == null) {
            throw new InvalidActionException("No active purchase");
        }
        if (currentPurchase.getEntries() != null) {
            for (PurchaseEntry entry : currentPurchase.getEntries()) {
                if (entry.getItem().equals(stock.getItem())) {
                    stockModule.addStock(stock.getItem(), qty);
                    entry.setQty(entry.getQty() + qty);
                    return;
                }
            }
        }
        PurchaseEntry entry = new PurchaseEntry();
        entry.setItem(stock.getItem());
        entry.setQty(qty);
        entry.setPurchaseRate(stock.getItem().getUnitPrice());
        entry.setExclusiveTax(stock.getItem().getExclusiveTax());
        stockModule.addStock(stock.getItem(), qty);
        currentPurchase.addEntry(entry);
    }

    public void addStock(Stock stock, double qty, double purchaseRate, double exclTax) {
        if (txn == null || !txn.isActive()) {
            throw new InvalidActionException("No active purchase");
        }
        PurchaseEntry entry = new PurchaseEntry();
        entry.setItem(stock.getItem());
        entry.setQty(qty);
        entry.setPurchaseRate(purchaseRate);
        entry.setExclusiveTax(exclTax);
        stockModule.addStock(stock, qty);
        currentPurchase.addEntry(entry);
    }

    public void cancelPurchase(Purchase purchase) {
        if (txn != null && txn.isActive()) {
            txn.rollback();
        }
        txn = null;
        txn = em.getTransaction();
        txn.begin();
        purchaseModule.cancelPurchase(purchase);
        txn.commit();
        txn = null;
    }

    public List<Purchase> getAllPurchases() {
        return purchaseModule.getAllPurchases();
    }

    public List<Purchase> getAllPurchasesBilledOn(Date date) {
        return purchaseModule.getAllPurchasesBilledOn(date);
    }

    public List<Purchase> getAllActivePurchases() {
        return purchaseModule.getAllActivePurchases();
    }

    public List<Purchase> getActivePurchasesBilledOn(Date date) {
        return purchaseModule.getActivePurchasesBilledOn(date);
    }

    public List<Purchase> getAllCancelledPurchases() {
        return purchaseModule.getAllCancelledPurchases();
    }

    public List<Purchase> getCancelledPurchasesBilledOn(Date date) {
        return purchaseModule.getCancelledPurchasesBilledOn(date);
    }

    public List<PurchaseEntry> getAllPurchaseEntriesForItem(Item item) {
        return purchaseModule.getAllPurchaseEntriesForItem(item);
    }

    public List<PurchaseEntry> getActivePurchaseEntriesForItem(Item item) {
        return purchaseModule.getActivePurchaseEntriesForItem(item);
    }

    public List<PurchaseEntry> getCancelledPurchaseEntriesForItem(Item item) {
        return purchaseModule.getCancelledPurchaseEntriesForItem(item);
    }

    public List<Purchase> getAllPurchasesBetween(Date startDate, Date endDate) {
        return purchaseModule.getAllPurchasesBetween(startDate, endDate);
    }

    public List<Purchase> getActivePurchasesBetween(Date startDate, Date endDate) {
        return purchaseModule.getActivePurchasesBetween(startDate, endDate);
    }

    public List<Purchase> getCancelledPurchasesBetween(Date startDate, Date endDate) {
        return purchaseModule.getCancelledPurchasesBetween(startDate, endDate);
    }

    public Purchase getPurchase(String id) {
        return purchaseModule.getPurchase(id);
    }
}
